package testDataGenerator.model;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Element;

import testDataGenerator.model.exception.InvalidGenerationOptionException;
import testDataGenerator.model.exception.MultipleUniqueColumnException;

public class DataSet {
	private String uniqueName;
	private List<DataColumn> dataColumns;
	private String outputFormat;
	private int numberOfRows;
	private String outputFilePath;
	private List<String[]> data;
	private GenerationMethodFactory generationMethodFactory;
	private DataTypeFactory dataTypeFactory;

	public DataSet(Element element, DataTypeFactory dataTypeFactory,
			GenerationMethodFactory generationMethodFactory) throws MultipleUniqueColumnException{
		this.dataTypeFactory = dataTypeFactory;
		this.generationMethodFactory = generationMethodFactory;
		setAttributesFromElement(element);
		if(hasMoreThanOneUniqueColumn())
			throw new MultipleUniqueColumnException();
//		generateData();
	}

	private boolean hasMoreThanOneUniqueColumn() {
		int count = 0;
		for(DataColumn column: this.dataColumns){
			if(column.isPrimaryKey())
				count ++;
		}
		if(count>1)
			return true;
		else
			return false;
	}

	private void setAttributesFromElement(Element element) {
		this.uniqueName = element.attributeValue("uniqueName");
		dataColumns = new ArrayList<DataColumn>();
		for (Iterator<DataColumn> i = element.elementIterator(); i.hasNext();) {
			Element item = (Element) i.next();
			String name = item.getName();
			if (name.equals("dataColumn")) {
				dataColumns.add(new DataColumn(item, generationMethodFactory,
						dataTypeFactory));
			}
			if (name.equals("outputFormat")) {
				this.outputFormat = item.getStringValue();
			}
			if (name.equals("outputFilePath")) {
				this.outputFilePath = item.getStringValue();
			}
			if (name.equals("numberOfRows")) {
				this.numberOfRows = new Integer(item.getStringValue())
						.intValue();
			}
		}
	}

	public String getUniqueName() {
		return this.uniqueName;
	}

	public List getDataColumns() {
		return this.dataColumns;
	}

	public String getOutputFormat() {
		return this.outputFormat;
	}

	public int getNumberOfRows() {
		return this.numberOfRows;
	}

	public String getOutputFilePath() {
		return this.outputFilePath;
	}

	public String toSql() {
		String sql = "";
		for (int i = 0; i < this.numberOfRows; i++) {
			sql = sql + "insert into " + this.uniqueName
					+ generateColumnTypesStr() + generateDataLineStr(i) + "\n";
		}
		return sql;
	}
	
	private String generateDataLineStr(int index) {
		 String data = " values (";
		 for(DataColumn dataColumn: this.dataColumns){
			 data = data + dataColumn.getData()[index] + ",";
		 }
		 data = data + ")";
		 data = data.replace(",)", ")");
		 return data;
	}

	private String generateColumnTypesStr() {
		String columnTypes = " (";
		for (DataColumn dataColumn : this.dataColumns) {
			columnTypes = columnTypes + dataColumn.getDataType().getName() + ",";
		}
		columnTypes = columnTypes + ")";
		columnTypes = columnTypes.replace(",)", ")");
		return columnTypes;
	}

	public void generateData() throws InvalidGenerationOptionException{
		data = new ArrayList<String[]>();
		for (DataColumn column: this.dataColumns) {
			String[] dataLine = column.generateData(this.numberOfRows);
			data.add(dataLine);
		}
	}
	
	public List<String[]> getData(){
		return this.data;
	}
}
